using System;
using System.Collections.Generic;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.TTC;
using OracleInternal.TTC.Accessors;

namespace OracleInternal.ServiceObjects
{
	internal class OracleBlobImpl
	{
		internal OracleConnectionImpl m_connectionImpl;

		internal byte[] m_lobLocator;

		internal string m_lobId;

		internal TTCBlob m_ttcBlob;

		internal bool m_caching;

		internal int m_chunkSize;

		internal long m_totalLobSize;

		internal bool m_bDbVaryingWidth;

		internal short m_clobCharSet;

		internal byte m_clobFormOfUse;

		internal long m_lobDataLength;

		internal bool m_isTemporaryLob;

		internal bool m_doneTempLobCreate;

		internal bool m_isEmpty;

		internal byte[] m_lobPrefetchData;

		private string m_id;

		internal int m_refCount = 1;

		private object m_lock = new object();

		internal bool IsValueLob
		{
			get
			{
				bool result = false;
				if (m_lobLocator != null)
				{
					result = TTCLob.IsValueBasedLocator(m_lobLocator);
				}
				return result;
			}
		}

		internal bool IsQuasiLobLocator
		{
			get
			{
				bool result = false;
				if (m_lobLocator != null)
				{
					result = TTCLob.IsQuasiLocator(m_lobLocator);
				}
				return result;
			}
		}

		internal OracleBlobImpl(OracleConnectionImpl connImpl, byte[] lobLocator, bool bCaching)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor);
			}
			try
			{
				m_id = GetHashCode().ToString();
				m_connectionImpl = connImpl;
				m_lobLocator = lobLocator;
				m_caching = bCaching;
				m_ttcBlob = new TTCBlob(connImpl.m_marshallingEngine);
				if (m_lobLocator != null)
				{
					m_lobId = GetLobIdString(m_lobLocator);
					if (IsTemporaryLob(m_lobLocator))
					{
						m_connectionImpl.TemporaryLobReferenceAdd(m_lobId, this);
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor, "(implid={0})", m_id);
				}
			}
		}

		internal OracleBlobImpl(OracleConnectionImpl connImpl, byte[] lobLocator)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor);
			}
			try
			{
				m_id = GetHashCode().ToString();
				m_connectionImpl = connImpl;
				m_lobLocator = lobLocator;
				m_ttcBlob = new TTCBlob(connImpl.m_marshallingEngine);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor, "(implid={0})", m_id);
				}
			}
		}

		internal OracleBlobImpl(int currentRow, OracleConnectionImpl connImpl, TTCLobAccessor lobAccessor)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor);
			}
			try
			{
				m_id = GetHashCode().ToString();
				m_connectionImpl = connImpl;
				m_lobDataLength = (int)lobAccessor.m_prefetchInfo.m_prefetchedDataLength[currentRow];
				m_totalLobSize = lobAccessor.m_prefetchInfo.m_totalLobSizeInDB[currentRow];
				m_lobLocator = lobAccessor.GetLobLocator(currentRow);
				List<ArraySegment<byte>> list = lobAccessor.m_prefetchInfo.m_prefetchedData[currentRow];
				if (list != null)
				{
					m_lobPrefetchData = new byte[m_lobDataLength];
					Accessor.CopyDataToUserBuffer(list, 0, m_lobPrefetchData, 0, (int)m_lobDataLength);
				}
				m_ttcBlob = new TTCBlob(connImpl.m_marshallingEngine);
				m_isTemporaryLob = TTCLob.IsTemporaryLob(m_lobLocator);
				if (m_isTemporaryLob)
				{
					m_doneTempLobCreate = true;
				}
				m_lobId = GetLobIdString(m_lobLocator);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor, "(implid={0})", m_id);
				}
			}
		}

		internal OracleBlobImpl(OracleConnectionImpl connImpl, TTCLobAccessor lobAccessor, DataUnmarshaller dataUnmarshaller, int currentRow, int columnIndex)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor);
			}
			try
			{
				m_id = GetHashCode().ToString();
				m_connectionImpl = connImpl;
				lobAccessor.GetLobData(dataUnmarshaller, currentRow, columnIndex, out m_lobLocator, out var prefetchCtx);
				if (prefetchCtx != null)
				{
					m_lobPrefetchData = prefetchCtx.m_lobPrefetchData;
					m_chunkSize = prefetchCtx.m_chunkSize;
					m_clobCharSet = prefetchCtx.m_clobCharSet;
					m_clobFormOfUse = prefetchCtx.m_clobFormOfUse;
					m_bDbVaryingWidth = prefetchCtx.m_bDbVaryingWidth;
					m_lobDataLength = prefetchCtx.m_lobDataLength;
					m_totalLobSize = prefetchCtx.m_totalLobSize;
				}
				m_ttcBlob = new TTCBlob(connImpl.m_marshallingEngine);
				m_isTemporaryLob = TTCLob.IsTemporaryLob(m_lobLocator);
				if (m_isTemporaryLob)
				{
					m_doneTempLobCreate = true;
				}
				m_lobId = GetLobIdString(m_lobLocator);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.ctor, "(implid={0})", m_id);
				}
			}
		}

		internal long GetLength()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.GetLength, "(implid={0})", m_id);
			}
			try
			{
				if (m_lobPrefetchData != null)
				{
					return m_totalLobSize;
				}
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					return m_ttcBlob.GetLength(m_lobLocator);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.GetLength, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.GetLength, "(implid={0})", m_id);
				}
			}
		}

		internal long SetLength(long newLength)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.SetLength, "(implid={0})", m_id);
			}
			try
			{
				long result;
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					result = m_ttcBlob.Trim(m_lobLocator, newLength);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
				m_lobPrefetchData = null;
				return result;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.SetLength, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.SetLength, "(implid={0})", m_id);
				}
			}
		}

		internal void CreateTemporaryLob()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.CreateTemporaryLob, "(implid={0})", m_id);
			}
			try
			{
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					m_lobLocator = m_ttcBlob.CreateTemporaryLob(m_caching, bNClob: false, 10);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
				m_lobId = GetLobIdString(m_lobLocator);
				m_connectionImpl.TemporaryLobReferenceAdd(m_lobId, this);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.CreateTemporaryLob, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.CreateTemporaryLob, "(implid={0})", m_id);
				}
			}
		}

		internal void FreeTemporaryLob()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.FreeTemporaryLob, "(implid={0})", m_id);
			}
			try
			{
				if (m_lobLocator == null || m_refCount != 0)
				{
					return;
				}
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					if (m_lobLocator != null && m_refCount == 0)
					{
						m_connectionImpl.AddAllPiggyBackRequests();
						m_ttcBlob.FreeTemporaryLob(m_lobLocator);
						m_lobLocator = null;
					}
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.FreeTemporaryLob, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.FreeTemporaryLob, "(implid={0})", m_id);
				}
			}
		}

		internal bool IsTemporaryLob()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.IsTemporaryLob, "(implid={0})", m_id);
			}
			bool result = true;
			try
			{
				if (m_lobLocator != null)
				{
					result = IsTemporaryLob(m_lobLocator);
				}
				return result;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.IsTemporaryLob, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.IsTemporaryLob, "(implid={0})", m_id);
				}
			}
		}

		internal long GetChunkSize()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.GetChunkSize, "(implid={0})", m_id);
			}
			try
			{
				if (m_lobPrefetchData != null)
				{
					return m_chunkSize;
				}
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					return m_ttcBlob.GetChunkSize(m_lobLocator);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.GetChunkSize, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.GetChunkSize, "(implid={0})", m_id);
				}
			}
		}

		internal bool Open()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Open, "(implid={0})", m_id);
			}
			try
			{
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					return m_ttcBlob.Open(m_lobLocator, 2);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Open, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Open, "(implid={0})", m_id);
				}
			}
		}

		internal bool Close()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Close, "(implid={0})", m_id);
			}
			bool result = true;
			try
			{
				if (m_lobLocator != null)
				{
					try
					{
						m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
						if (m_lobLocator != null)
						{
							result = m_ttcBlob.Close(m_lobLocator);
						}
					}
					finally
					{
						m_connectionImpl.m_connectionFreeToUseEvent.Set();
					}
				}
				return result;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Close, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Close, "(implid={0})", m_id);
				}
			}
		}

		internal static long CopyBlobDataInBytes(int currentRow, OracleConnectionImpl connImpl, TTCLobAccessor lobAccessor, long locatorOffset, byte[] outBuffer, int outBufferOffset, int numBytesToCopy)
		{
			long num = 0L;
			long num2 = 0L;
			bool bIsNClob = false;
			long prefetchedDataLength = 0L;
			long dataLengthInDB = 0L;
			List<ArraySegment<byte>> prefetchedData = null;
			lobAccessor.GetLOBPrefetchInfo(currentRow, out prefetchedData, out prefetchedDataLength, out dataLengthInDB, out bIsNClob);
			if (locatorOffset <= prefetchedDataLength)
			{
				num = Accessor.CopyDataToUserBuffer(prefetchedData, (int)locatorOffset - 1, outBuffer, outBufferOffset, numBytesToCopy);
				locatorOffset = 1L;
				outBufferOffset += (int)num;
				numBytesToCopy -= (int)num;
			}
			else
			{
				locatorOffset -= prefetchedDataLength;
			}
			num2 = num;
			if (numBytesToCopy > 0)
			{
				List<ArraySegment<byte>> list = lobAccessor.m_dataThroughLobArrayRead[currentRow];
				if (list != null && list.Count > 0)
				{
					num = Accessor.CopyDataToUserBuffer(list, (int)locatorOffset - 1, outBuffer, outBufferOffset, numBytesToCopy);
					num2 += num;
				}
			}
			return num2;
		}

		internal static byte[] GetCompleteBlobData(int currentRow, TTCLobAccessor lobAccessor)
		{
			bool bIsNClob = false;
			long prefetchedDataLength = 0L;
			long dataLengthInDB = 0L;
			List<ArraySegment<byte>> prefetchedData = null;
			lobAccessor.GetLOBPrefetchInfo(currentRow, out prefetchedData, out prefetchedDataLength, out dataLengthInDB, out bIsNClob);
			int userBuffOffset = 0;
			byte[] array = null;
			if (dataLengthInDB > 0)
			{
				array = new byte[dataLengthInDB];
			}
			if (prefetchedDataLength > 0)
			{
				userBuffOffset = Accessor.CopyDataToUserBuffer(prefetchedData, 0, array, 0, (int)prefetchedDataLength);
			}
			if (prefetchedDataLength < dataLengthInDB)
			{
				List<ArraySegment<byte>> list = lobAccessor.m_dataThroughLobArrayRead[currentRow];
				if (list != null && list.Count > 0)
				{
					Accessor.CopyDataToUserBuffer(list, 0, array, userBuffOffset, (int)(dataLengthInDB - prefetchedDataLength));
				}
			}
			return array;
		}

		internal static byte[] GetCompleteBlobData(int currentRow, int columnIndex, OracleConnectionImpl connImpl, byte[] lobLocator, DataUnmarshaller dataUnmarshaller, TTCLobAccessor lobAccessor, ref OracleBlobImpl oraBlobImpl)
		{
			byte[] outBuffer = null;
			if (!lobAccessor.m_bNullByDescribe)
			{
				if (lobLocator == null)
				{
					lobLocator = lobAccessor.GetLobLocator(currentRow);
				}
				int length = 0;
				long num = 0L;
				long num2 = 0L;
				long locatorOffset = 0L;
				long num3 = 0L;
				long outBufferOffset = 0L;
				if (lobLocator != null)
				{
					if (lobAccessor.m_marshallingEngine.DBVersion >= 11100)
					{
						dataUnmarshaller.StartAccumulatingColumnData(currentRow, columnIndex, null);
						dataUnmarshaller.UnmarshalUB4();
						num = dataUnmarshaller.UnmarshalSB8();
						outBuffer = new byte[num];
						num2 = ((num < lobAccessor.m_internalInitialLOBFS) ? num : lobAccessor.m_internalInitialLOBFS);
						dataUnmarshaller.UnmarshalUB4();
						if (lobAccessor.m_internalInitialLOBFS > 0)
						{
							dataUnmarshaller.UnmarshalCLR((int)num2, outBuffer, ref length);
						}
						dataUnmarshaller.StopAccumulatingColumnData();
						if (num > lobAccessor.m_internalInitialLOBFS)
						{
							locatorOffset = lobAccessor.m_internalInitialLOBFS + 1;
							num3 = num - lobAccessor.m_internalInitialLOBFS;
							outBufferOffset = lobAccessor.m_internalInitialLOBFS;
							if (oraBlobImpl == null)
							{
								oraBlobImpl = new OracleBlobImpl(connImpl, lobLocator);
							}
							else
							{
								oraBlobImpl.m_lobLocator = lobLocator;
							}
						}
					}
					else
					{
						if (oraBlobImpl == null)
						{
							oraBlobImpl = new OracleBlobImpl(connImpl, lobLocator);
						}
						else
						{
							oraBlobImpl.m_lobLocator = lobLocator;
						}
						num = oraBlobImpl.GetLength();
						outBuffer = new byte[num];
						locatorOffset = 1L;
						num3 = num;
						outBufferOffset = 0L;
					}
					if (num3 > 0)
					{
						oraBlobImpl.ReadDataFromDB(locatorOffset, num3, outBufferOffset, ref outBuffer);
					}
				}
			}
			return outBuffer;
		}

		internal void ReadDataFromDB(long locatorOffset, long numBytesToRead, long outBufferOffset, ref byte[] outBuffer)
		{
			long num = 0L;
			try
			{
				m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
				m_connectionImpl.AddAllPiggyBackRequests();
				num += m_ttcBlob.Read(m_lobLocator, locatorOffset, numBytesToRead, outBufferOffset, ref outBuffer);
			}
			finally
			{
				m_connectionImpl.m_connectionFreeToUseEvent.Set();
			}
		}

		internal long Read(long locatorOffset, long numBytesToRead, long outBufferOffset, ref byte[] outBuffer)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Read, "(implid={0})", m_id);
			}
			long num = 0L;
			try
			{
				if (m_lobPrefetchData != null)
				{
					long lobDataLength = m_lobDataLength;
					if (locatorOffset <= lobDataLength)
					{
						if (locatorOffset - 1 + numBytesToRead <= lobDataLength || lobDataLength >= m_totalLobSize)
						{
							Array.Copy(m_lobPrefetchData, (int)(locatorOffset - 1), outBuffer, (int)outBufferOffset, m_lobPrefetchData.Length);
							return numBytesToRead;
						}
						Array.Copy(m_lobPrefetchData, (int)(locatorOffset - 1), outBuffer, (int)outBufferOffset, lobDataLength);
						outBufferOffset += lobDataLength;
						locatorOffset += lobDataLength;
						numBytesToRead -= lobDataLength;
						num += lobDataLength;
					}
				}
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					num += m_ttcBlob.Read(m_lobLocator, locatorOffset, numBytesToRead, outBufferOffset, ref outBuffer);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
				return num;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Read, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Read, "(implid={0})", m_id);
				}
			}
		}

		internal long Write(long locatorOffset, byte[] inBuffer, long inBufferOffset, long numBytesToWrite)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Write, "(implid={0})", m_id);
			}
			try
			{
				long result;
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					result = m_ttcBlob.Write(m_lobLocator, locatorOffset, inBuffer, inBufferOffset, numBytesToWrite);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
				m_lobPrefetchData = null;
				return result;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Write, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Write, "(implid={0})", m_id);
				}
			}
		}

		internal long Erase(long locatorOffset, long numBytesToErase)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Erase, "(implid={0})", m_id);
			}
			try
			{
				long result;
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					result = m_ttcBlob.Erase(m_lobLocator, locatorOffset, numBytesToErase);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
				m_lobPrefetchData = null;
				return result;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Erase, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Erase, "(implid={0})", m_id);
				}
			}
		}

		internal void Append(byte[] srcLobLocator)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Append, "(implid={0})", m_id);
			}
			try
			{
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					m_ttcBlob.Append(srcLobLocator, m_lobLocator);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
				m_lobPrefetchData = null;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Append, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.Append, "(implid={0})", m_id);
				}
			}
		}

		internal long CopyTo(byte[] destLobLocator, long srcOffset, long dstOffset, long dataLen)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.CopyTo, "(implid={0})", m_id);
			}
			long result = 0L;
			try
			{
				try
				{
					m_connectionImpl.m_connectionFreeToUseEvent.WaitOne();
					m_connectionImpl.AddAllPiggyBackRequests();
					result = m_ttcBlob.Copy(m_lobLocator, destLobLocator, srcOffset, dstOffset, dataLen);
				}
				finally
				{
					m_connectionImpl.m_connectionFreeToUseEvent.Set();
				}
				return result;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.CopyTo, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.CopyTo, "(implid={0})", m_id);
				}
			}
		}

		internal void AddRef()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.AddRef, "(implid={0}) (total={1})", m_id, m_refCount.ToString());
			}
			try
			{
				lock (m_lock)
				{
					m_refCount++;
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.AddRef, "(implid={0}) (total={1})", m_id, m_refCount.ToString());
				}
			}
		}

		internal void RelRef()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.RelRef, "(implid={0}) (total={1})", m_id, m_refCount.ToString());
			}
			try
			{
				lock (m_lock)
				{
					m_refCount--;
					if (m_refCount == 0 && ((m_isTemporaryLob && m_doneTempLobCreate) || IsTemporaryLob()))
					{
						if (m_lobLocator != null)
						{
							m_connectionImpl.AddTempLOBsToBeFreed(m_lobLocator);
						}
						if (m_lobId != null)
						{
							m_connectionImpl.TemporaryLobReferenceRemove(m_lobId);
						}
					}
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.RelRef, "(implid={0}) (total={1})", m_id, m_refCount.ToString());
				}
			}
		}

		internal int GetRefCount()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.GetRefCount, "(implid={0})", m_id);
			}
			try
			{
				return m_refCount;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleBlobImpl, OracleTraceFuncName.GetRefCount, "(implid={0}) (total={1})", m_id, m_refCount.ToString());
				}
			}
		}

		internal static bool IsTemporaryLob(byte[] lobLocator)
		{
			return TTCLob.IsTemporaryLob(lobLocator);
		}

		internal static byte[] GetLobId(byte[] lobLocator)
		{
			return TTCLob.GetLobId(lobLocator);
		}

		internal static string GetLobIdString(byte[] lobLocator)
		{
			return TTCLob.GetLobIdString(lobLocator);
		}
	}
}
